package hasthi.tools.systemstat;

import hasthi.common.HasthiException;
import hasthi.manager.ManagerAddress;
import hasthi.manager.QueryResults;
import hasthi.manager.SystemStatsDocument;
import hasthi.manager.SystemStatsDocument.SystemStats;
import hasthi.metamodel.resource.ManagedResource;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SystemStat {
    private Map<String, GroupStat> resourceStats = new ConcurrentHashMap<String, GroupStat>();
    
    private int resourceCount;
    private int managerCount;
    private double memoryUsage;
    private double loadAverage;
    private ManagerAddress coordiantorAddress;
    
    //private int
    public void reset(){
        for(GroupStat groupStat:resourceStats.values()){
            groupStat.reset();
        }
    }
    
    public void update(ManagedResource resource) throws HasthiException{
        String state = resource.getState();
        GroupStat groupStat = resourceStats.get(state);
        if(groupStat == null){
            groupStat = new GroupStat();
            resourceStats.put(state, groupStat);
        }
        groupStat.update(resource, 1);
    }

    public int getResourceCount() {
        return resourceCount;
    }

    public void setResourceCount(int resourceCount) {
        this.resourceCount = resourceCount;
    }

    public int getManagerCount() {
        return managerCount;
    }

    public void setManagerCount(int managerCount) {
        this.managerCount = managerCount;
    }

    public double getMemoryUsage() {
        return memoryUsage;
    }

    public void setMemoryUsage(double memoryUsage) {
        this.memoryUsage = memoryUsage;
    }

    public double getLoadAverage() {
        return loadAverage;
    }

    public void setLoadAverage(double loadAverage) {
        this.loadAverage = loadAverage;
    }
    
    
    public SystemStatsDocument getSystemStatusData(){
        try {
            SystemStatsDocument statsDocument = SystemStatsDocument.Factory.newInstance();
            
            SystemStats systemStats = statsDocument.addNewSystemStats();
            systemStats.setCoordinatorAddress(coordiantorAddress);
            systemStats.setManagerCount(managerCount);
            systemStats.setLoadAverage(loadAverage);
            systemStats.setResourceCount(resourceCount);
            systemStats.setMemoryUsage(memoryUsage);
            
            for(String name:resourceStats.keySet()){
                GroupStat groupStat = resourceStats.get(name);
                QueryResults result = systemStats.addNewQueryResults();
                result.setQuery(createQueryName(ManagedResource.ResourceType.Host.toString(), name));
                result.setCount(groupStat.getHostCount());
                
                result = systemStats.addNewQueryResults();
                result.setQuery(createQueryName(ManagedResource.ResourceType.Service.toString(), name));
                result.setCount(groupStat.getServiceCount());
                
                result = systemStats.addNewQueryResults();
                result.setQuery(createQueryName(ManagedResource.ResourceType.TransientService.toString(), name));
                result.setCount(groupStat.getTransientServiceCount());

                result = systemStats.addNewQueryResults();
                result.setQuery(createQueryName(ManagedResource.ResourceType.ComputeNode.toString(), name));
                result.setCount(groupStat.getComputeNodeCount());
            }
            
            return statsDocument;
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    
    private String createQueryName(String type,String status){
        StringBuffer buffer = new StringBuffer();
        buffer.append("type=").append(type).append(",").append("state=").append(status);
        return buffer.toString();
    }

    public void setCoordiantorAddress(ManagerAddress coordiantorAddress) {
        this.coordiantorAddress = coordiantorAddress;
    }

  
}
